5299
4120
在HTML中作為背景色輸入時,某些隨機字符串如何產生顏色?例如:
測試
...在所有瀏覽器和平台上產生背景為紅色的文檔。
有趣的是,雖然恰克諾里也產生紅色背景,但恰克諾爾產生黃色背景。
這裡發生了什麼? 
這是Netscape時代的一大亮點:
丟失的數字被視為0 [...]。不正確的數字被簡單地解釋為0。例如,值#F0F0F0,F0F0F0,F0F0F,#FxFxFx和FxFxFx都相同。
它來自博客文章關於Microsoft Internet Explorer的顏色解析的一點怨言,其中涵蓋了它的詳細信息,包括不同長度的顏色值等。
如果我們從博客文章中依次應用規則,則會得到以下信息:
將所有無效的十六進製字符替換為0:
查克諾里斯成為c00c0000000
填充到下一個可被3(11→12)整除的字符總數:
c00c 0000 0000
分為三個相等的組,每個分量代表RGB顏色的相應顏色分量:
RGB(c00c,0000,0000)
將每個參數從右向下截斷為兩個字符。
最後,得出以下結果:
RGB(c0,00,00)=#C00000或RGB(192,0,0)
這是一個演示bgcolor屬性在運行中以產生此“驚人”色樣的示例:
<表格>

查克·諾里斯
 T先生
 ninjaturtle 


生病
廢話


這也回答了問題的另一部分:為什麼bgcolor =“ chucknorr”產生黃色?好吧,如果我們應用規則,則字符串為:
c00c00000 => c00 c00 000 => c0 c0 00 [RGB(192,192,0)]
呈淺金黃色。由於字符串以9個字符開頭,因此我們這次保持第二個“ C”,因此最終以最終顏色值結束。
我最初遇到此問題的原因是有人指出您可以進行color =“ crap”,然後變成褐色。
|
抱歉,我不同意,但是根據解析@Yuhong Bao發布的舊色值的規則,chucknorris不等於#CC0000,而是等於#C00000,這是非常相似但略有不同的紅色。我使用Firefox ColorZilla加載項進行了驗證。
規則規定:
通過添加0將字符串的長度設為3的倍數:chucknorris0
將字符串分成3個相等長度的字符串:chuc knor ris0
將每個字符串截斷為2個字符:ch kn ri
保留十六進制值,並在必要時添加0:C0 00 00
我能夠使用這些規則正確解釋以下字符串:
幸運符
運氣
幸運珠
今晚運氣好
江南風格
更新:原來說顏色為#CC0000的原始答复者已經編輯了他們的答案以包括更正。
|
大多數瀏覽器將只忽略顏色字符串中的任何非十六進制值,而將非十六進制數字替換為零。
ChuCknorris轉換為c00c0000000。此時,瀏覽器會將字符串分為三個相等的部分,分別指示紅色,綠色和藍色值:c00c 00000000。每個部分中的多餘位將被忽略,這將使最終結果#c00000為帶紅色。
請注意,這不適用於遵循CSS標準的CSS顏色解析。

偏紅

與上述相同

黑色 | 原因是瀏覽器無法理解它,並嘗試以某種方式將其轉換為它可以理解的值,在這種情況下,將其轉換為十六進制值! chucknorris以c開頭,它是十六進制的可識別字符,它還將所有無法識別的字符轉換為0! 因此,十六進制格式的chucknorris變為:c00c00000000,所有其他字符變為0,c保留在它們所在的位置... 現在它們被RGB(紅色,綠色,藍色)除以3 ... R:c00c,G:0000,B:0000 ... 但是我們知道RGB的有效十六進制只有2個字符,表示R:c0,G:00,B:00 因此,實際結果是: bgcolor =“#c00000”; 我還在圖像中添加了步驟,為您提供了快速參考: | 瀏覽器試圖將chucknorris轉換為十六進制顏色代碼,因為該值無效。 在chucknorris中,除c外的所有值都不是有效的十六進制值。 因此將其轉換為c00c00000000。 變成#c00000,紅色陰影。 這似乎主要是與Internet Explorer和Opera(12)有關的問題,因為Chrome(31)和Firefox(26)都忽略了這一點。 附言括號中的數字是我測試過的瀏覽器版本。 輕一點 Chuck Norris不符合網絡標準。 Web標準符合 給他。 #BADA55 | WHATWG HTML規範具有解析舊版顏色的確切算法值: https://html.spec.whatwg.org/multipage/infrastructure.html#rules-for-parsing-a-legacy-colour-value。 用於解析顏色字符串的Netscape Classic代碼是開源的: https://dxr.mozilla.org/classic/source/lib/layout/layimage.c#155。 例如,請注意,每個字符都被解析為十六進制數字,然後在不檢查溢出的情況下被轉換為32位整數。 32位整數只能容納8個十六進制數字,這就是為什麼只考慮最後8個字符的原因。將十六進制數字解析為32位整數後,然後將它們除以16,直到它們適合8位,然後將其截斷為8位整數,這就是為什麼忽略前導零的原因。 更新:該代碼與規範中定義的代碼不完全匹配,但是唯一的區別是幾行代碼。我認為是添加了以下幾行(在Netscape 4中): 如果(bytes_per_val> 4) { bytes_per_val = 4; } | 回答: 瀏覽器將嘗試將chucknorris轉換為十六進制值。 由於c是chucknorris中唯一有效的十六進製字符,因此該值變為:c00c00000000(對於所有無效的值均為0)。 然後,瀏覽器將結果分為3組:紅色= c00c,綠色= 0000,藍色= 0000。 由於html背景的有效十六進制值僅包含每種顏色類型(r,g,b)的2位數字,因此每組的最後2位數字均被截斷,從而使rgb值c00000為磚紅色調色調。 | chucknorris以c開頭,瀏覽器將其讀取為十六進制值。 因為A,B,C,D,E和F是十六進製字符。 瀏覽器將chucknorris轉換為十六進制值C00C00000000。 然後將C00C00000000十六進制值轉換為RGB格式(除以3): C00C00000000⇒R:C00C,G:0000,B:0000 瀏覽器僅需要兩位數字來指示顏色: R:C00C,G:0000,B:0000⇒R:C0,G:00,B:00⇒C00000 最後,在網絡瀏覽器中顯示bgcolor = C00000。 這是一個演示它的示例: <表格> chucknorris c00c00000000 c00000 | 解析舊屬性上的顏色的規則涉及到比現有答案中提到的步驟更多的步驟。將截斷部分轉換為兩位數的部分描述為: 丟棄除最後8個字符以外的所有字符 只要所有組件都具有前導零,則一一丟棄前導零。 丟棄除前2個字符外的所有字符 一些例子: oooFoooFoooF 000F 000F 000F <-替換,填充和塊 0F 0F 0F <-前導零被截斷 0F 0F 0F <-從右截去2個字符 oooFooFFoFFF 000F 00FF 0FFF <-替換,填充和塊 00F 0FF FFF <-前導零被截斷 00 0F FF <-從右邊截斷為2個字符 ABCooooooABCooooooABCoooooo ABC000000 ABC000000 ABC000000 <-替換,填充和塊 BC000000 BC000000 BC000000 <-從左開始被截斷為8個字符 BC BC BC <-從右截去2個字符 AoCooooooAoCooooooAoCoooooo A0C000000 A0C000000 A0C000000 <-替換,填充和塊 0C000000 0C000000 0C000000 <-從左開始被截斷為8個字符 C000000 C000000 C000000 <-前導零被截斷 C0 C0 C0 <-從右截去2個字符 以下是該算法的部分實現。它不處理錯誤或用戶輸入有效顏色的情況。 函數parseColor(input){ // todo:如果輸入為“”,則返回錯誤 輸入= input.trim(); // todo:如果輸入為“透明”,則返回錯誤 // todo:如果輸入為命名顏色,則返回相應的#rrggbb // todo:如果輸入匹配#rgb,則返回#rrggbb // todo:將大於U + FFFF的Unicode代碼點替換為00 如果(input.length> 128){ 輸入= input.slice(0,128); } 如果(input.charAt(0)===“#”){ 輸入= input.slice(1); } 輸入= input.replace(/ [^ 0-9A-Fa-f] / g,“ 0”); 而(input.length === 0 || input.length%3> 0){ 輸入+ =“ 0”; } var r = input.slice(0,input.length / 3); var g = input.slice(input.length / 3,input.length * 2/3); var b = input.slice(input.length * 2/3); 如果(r.length> 8){ r = r.slice(-8); g = g.slice(-8); b = b.slice(-8); } while(r.length> 2 && r.charAt(0)===“ 0” && g.charAt(0)===“ 0” && b.charAt(0)===“ 0”){ r = r.slice(1); g = g.slice(1); b = b.slice(1); } 如果(r.length> 2){ r = r.slice(0,2); g = g.slice(0,2); b = b.slice(0,2); } 返回“#” + r.padStart(2,“ 0”)+ g.padStart(2,“ 0”)+ b.padStart(2,“ 0”); } $(function(){ $(“#input”)。on(“ change”,function(){ var input = $(this).val(); var color = parseColor(input); var $ cells = $(“#result tbody td”); $ cells.eq(0).attr(“ bgcolor”,輸入); $ cells.eq(1).attr(“ bgcolor”,color); 變種值: https://html.spec.whatwg.org/multipage/infrastructure.html#rules-for-parsing-a-legacy-colour-value。 用於解析顏色字符串的Netscape Classic代碼是開源的: https://dxr.mozilla.org/classic/source/lib/layout/layimage.c#155。 例如,請注意,每個字符都被解析為十六進制數字,然後在不檢查溢出的情況下被轉換為32位整數。 32位整數只能容納8個十六進制數字,這就是為什麼只考慮最後8個字符的原因。將十六進制數字解析為32位整數後,然後將它們除以16,直到它們適合8位,然後將其截斷為8位整數,這就是為什麼忽略前導零的原因。 更新:該代碼與規範中定義的代碼不完全匹配,但是唯一的區別是幾行代碼。我認為是添加了以下幾行(在Netscape 4中): 如果(bytes_per_val> 4) { bytes_per_val = 4; } | 回答: 瀏覽器將嘗試將chucknorris轉換為十六進制值。 由於c是chucknorris中唯一有效的十六進製字符,因此該值變為:c00c00000000(對於所有無效的值均為0)。 然後,瀏覽器將結果分為3組:紅色= c00c,綠色= 0000,藍色= 0000。 由於html背景的有效十六進制值僅包含每種顏色類型(r,g,b)的2位數字,因此每組的最後2位數字均被截斷,從而使rgb值c00000為磚紅色調色調。 | chucknorris以c開頭,瀏覽器將其讀取為十六進制值。 因為A,B,C,D,E和F是十六進製字符。 瀏覽器將chucknorris轉換為十六進制值C00C00000000。 然後將C00C00000000十六進制值轉換為RGB格式(除以3): C00C00000000⇒R:C00C,G:0000,B:0000 瀏覽器僅需要兩位數字來指示顏色: R:C00C,G:0000,B:0000⇒R:C0,G:00,B:00⇒C00000 最後,在網絡瀏覽器中顯示bgcolor = C00000。 這是一個演示它的示例: <表格> chucknorris c00c00000000 c00000 | 解析舊屬性上的顏色的規則涉及到比現有答案中提到的步驟更多的步驟。將截斷部分轉換為兩位數的部分描述為: 丟棄除最後8個字符以外的所有字符 只要所有組件都具有前導零,則一一丟棄前導零。 丟棄除前2個字符外的所有字符 一些例子: oooFoooFoooF 000F 000F 000F <-替換,填充和塊 0F 0F 0F <-前導零被截斷 0F 0F 0F <-從右截去2個字符 oooFooFFoFFF 000F 00FF 0FFF <-替換,填充和塊 00F 0FF FFF <-前導零被截斷 00 0F FF <-從右邊截斷為2個字符 ABCooooooABCooooooABCoooooo ABC000000 ABC000000 ABC000000 <-替換,填充和塊 BC000000 BC000000 BC000000 <-從左開始被截斷為8個字符 BC BC BC <-從右截去2個字符 AoCooooooAoCooooooAoCoooooo A0C000000 A0C000000 A0C000000 <-替換,填充和塊 0C000000 0C000000 0C000000 <-從左開始被截斷為8個字符 C000000 C000000 C000000 <-前導零被截斷 C0 C0 C0 <-從右截去2個字符 以下是該算法的部分實現。它不處理錯誤或用戶輸入有效顏色的情況。 函數parseColor(input){ // todo:如果輸入為“”,則返回錯誤 輸入= input.trim(); // todo:如果輸入為“透明”,則返回錯誤 // todo:如果輸入為命名顏色,則返回相應的#rrggbb // todo:如果輸入匹配#rgb,則返回#rrggbb // todo:將大於U + FFFF的Unicode代碼點替換為00 如果(input.length> 128){ 輸入= input.slice(0,128); } 如果(input.charAt(0)===“#”){ 輸入= input.slice(1); } 輸入= input.replace(/ [^ 0-9A-Fa-f] / g,“ 0”); 而(input.length === 0 || input.length%3> 0){ 輸入+ =“ 0”; } var r = input.slice(0,input.length / 3); var g = input.slice(input.length / 3,input.length * 2/3); var b = input.slice(input.length * 2/3); 如果(r.length> 8){ r = r.slice(-8); g = g.slice(-8); b = b.slice(-8); } while(r.length> 2 && r.charAt(0)===“ 0” && g.charAt(0)===“ 0” && b.charAt(0)===“ 0”){ r = r.slice(1); g = g.slice(1); b = b.slice(1); } 如果(r.length> 2){ r = r.slice(0,2); g = g.slice(0,2); b = b.slice(0,2); } 返回“#” + r.padStart(2,“ 0”)+ g.padStart(2,“ 0”)+ b.padStart(2,“ 0”); } $(function(){ $(“#input”)。on(“ change”,function(){ var input = $(this).val(); var color = parseColor(input); var $ cells = $(“#result tbody td”); $ cells.eq(0).attr(“ bgcolor”,輸入); $ cells.eq(1).attr(“ bgcolor”,color); 變種